package com.tdcy.framework.dao.metadata;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.tdcy.framework.exception.BaseException;
import com.tdcy.framework.util.StringUtils;

/**
 * The Class DatabaseMetadata.
 */
public class DatabaseMetadata {

	/** The meta. */
	private DatabaseMetaData meta;

	/** The Constant TYPES. */
	private static final String[] TYPES = { "TABLE", "VIEW" };

	/** The catalog. */
	private final String catalog;

	/** The schema. */
	private final String schema;

	/**
	 * Instantiates a new database metadata.
	 * 
	 * @param connection
	 *            the connection
	 */
	public DatabaseMetadata(final Connection connection) {
		try {
			meta = connection.getMetaData();
			catalog = null;
			schema = "public";
		} catch (Exception ex) {
			throw new BaseException("获取数据库结构信息出错", ex);
		}
	}

	/**
	 * Gets the table metadata.
	 * 
	 * @param name
	 *            the name
	 * @return the table metadata
	 */
	public TableMetadata getTableMetadata(final String name) {
		return getTableMetadata(catalog, schema, name);
	}

	/**
	 * Gets the table metadata.
	 * 
	 * @param catalog
	 *            the catalog
	 * @param schema
	 *            the schema
	 * @param name
	 *            the name
	 * @return the table metadata
	 */
	public TableMetadata getTableMetadata(final String catalog, final String schema, final String name) {
		TableMetadata tmd = null;
		try {
			ResultSet rs = null;
			try {
				if (schema.indexOf(",") > 0) {
					String[] schemaArray = schema.split(",");
					for (int i = 0; i < schemaArray.length; i++) {
						tmd = getTableMetadataWithSchema(catalog, schemaArray[i], name);
						if (tmd != null) {
							break;
						}
					}
				} else {
					tmd = getTableMetadataWithSchema(catalog, schema, name);
				}

				if (tmd == null) {
					throw new BaseException("表" + name + "不存在");
				} else {
					return tmd;
				}
			} finally {
				if (rs != null)
					rs.close();
			}
		} catch (SQLException sqle) {
			throw new BaseException("获取" + name + "表结构出错", sqle);
		}
	}

	private TableMetadata getTableMetadataWithSchema(final String catalog, final String schema, final String name) {
		try {
			ResultSet rs = null;
			try {
				if (meta.storesUpperCaseIdentifiers()) {
					rs = meta.getTables(StringUtils.toUpperCase(catalog), StringUtils.toUpperCase(schema), StringUtils.toUpperCase(name), TYPES);
				} else if (meta.storesLowerCaseIdentifiers()) {
					rs = meta.getTables(StringUtils.toLowerCase(catalog), StringUtils.toLowerCase(schema), StringUtils.toLowerCase(name), TYPES);
				} else {
					rs = meta.getTables(catalog, schema, name, TYPES);
				}

				while (rs.next()) {
					String tableName = rs.getString("TABLE_NAME");
					if (name.equalsIgnoreCase(tableName)) {
						return new TableMetadata(rs, meta);
					}
				}

				return null;
			} finally {
				if (rs != null)
					rs.close();
			}
		} catch (SQLException sqle) {
			throw new BaseException("获取" + name + "表结构出错", sqle);
		}
	}
}
